/*-*-C-*-
 * windowedit include file
 */

#ifndef __windowedit_h
#define __windowedit_h


#define  Window_PlotGadget  0x828bf   /* Toolbox SWI to plot gadgets */

/* allows forward references to GadgetPtr's */
typedef struct _gadgetrec GadgetRec, *GadgetPtr;

/***************************************************************************/

/*
 * The properties and structure of each gadget type are defined by a
 *  structure of type GadgetDefRec.
 *
 * This structure is interpreted at run-time to:
 *   - load a gadget from a window template
 *   - save a gadget to a window template
 *   - create a copy of a gadget record
 *   - delete a gadget record
 *   - fill in a gadget property dialogue box from a gadget record
 *   - update a gadget property dialogue box according to user interactions
 *   - update a gadget record from the corresponding property dialogue box
 *
 * Each gadget template (inside a window template) consists of a gadget
 *  template header record followed by a gadget template body record.
 *
 * Once a window template has been loaded, each gadget template is held as a
 *  gadget record (GadgetRec) in a linked list addressed from the window
 *  record (WindowObjRec). The gadget record consists of some internal fields
 *  (such as whether the gadget is selected or not, and whether its
 *  properties dialogue box is open) followed by a gadget header record
 *  (GadgetHeaderRec) and gadget body record (GadgetBodyRec). These header
 *  and body records have identical size and structure to the corresponding
 *  template header and body records - except that any StringReference or
 *  MsgReference fields have been "relocated" and are now char* fields.
 *
 * One of the internal fields at the head of a gadget record is a
 *  GadgetDefPtr which addresses the structure which describes the detailed
 *  structure and properties of the gadget type.
 */


/*
 * The RefDefRec structure provides information about a field which requires
 *  relocation.
 */

#define  REF_STR       (0)   /* a StringReference field */
#define  REF_MSG       (1)   /* a MsgReference field */
#define  REF_STRORMSG  (2)   /* contains either a String or Msg-Reference */
#define  REF_SPRITE    (3)   /* contains a SpriteAreaReference */
#define  REF_END       (4)   /* this terminates an array of reference defs */

typedef struct
{
    int type;
    int offset;
    Bool emptyisnull;        /* ignored if type is REF_SPRITE */
  /* the following two fields are valid only if type = REF_STRORMSG */
    unsigned mask;           /* mask defining flags bit which determines
                                whether the field is a StringReference or
                                MsgReference */
    unsigned ismsg;          /* value of flag bit which says its a MsgRef */
} RefDefRec, *RefDefPtr;


/*
 * This structure identifies those fields inside a gadget body which need to
 *  be relocated when the gadget is loaded or saved.
 *
 * Each of the pointer fields addresses a sequence of definitions which is
 *  terminated by a REF_END definition.
 *
 * The 'refs' array is generated dynamically for unknown gadget types when
 *  such a gadget is loaded; the 'usecount' field keeps track of how many
 *  copies of the gadget have been made, and is used to determine when the
 *  array can be freed.
 */

typedef struct
{
    int size;          /* gadget body size in bytes */
    int usecount;      /* for unknown gadget types only */
    RefDefPtr refs;    /* describes each relocation; must not be NULL */
} BodyDefRec, *BodyDefPtr;


/*
 * The following structures define the relationships between fields in a
 *  gadget record and fields in its properties dialogue box.
 *
 * Each (group of) fields is defined by a FieldDefRec, which includes all
 *  the information needed at run-time to transfer data in either direction
 *  between a gadget record and the corresponding dbox.
 *
 * For example, a FieldDefRec that points to an IntegerFldRec describes a
 *  simple integer field in a gadget record - for example, the componentID
 *  field:
 *     - 'valicon' gives the number of the icon in the dbox which is to
 *        contain the value
 *     - 'offset' is the offset of the field which contains the value
 *        (relative to the start of the gadget header record)
 *     - 'displayashex' is TRUE iff the value is to be displayed in hex
 *        inside the dialogue box.
 *
 * Each type of field is identified by one of the following #defines.
 */


#define  FLD_INTEGER         (0)  /* simple integer writable */
#define  FLD_MAND_ASS_STR    (1)  /* mandatory assignable string field:
                                      value, length and adjuster icons */
#define  FLD_OPT_ASS_STR     (2)  /* optional assignable string field:
                                      as above, plus option icon */
#define  FLD_MAND_CONST_STR  (3)  /* simple string field! */
#define  FLD_OPT_CONST_STR   (4)  /* optional simple string field */
#define  FLD_FLAG            (5)  /* option icon linked to gadget flag bit */
#define  FLD_XFLAG           (6)  /* option icon linked to a bit in a flags
                                      word in the gadget's body */
#define  FLD_XPACKED         (7)  /* integer writable linked to a subfield
                                      within a flags word in the gadget's
                                      body */
#define  FLD_BITS            (8)  /* option icon linked to bits field in
                                      gadget flags word */
#define  FLD_MAND_EVENT      (9)  /* event can be default or other */
#define  FLD_OPT_EVENT      (10)  /* event can be none, default or other */
#define  FLD_ALLOWABLE      (11)  /* validation string interface */
#define  FLD_LINK           (12)  /* before/after links between gadgets */
#define  FLD_COLOUR         (13)  /* colour display icon linked to subfield
                                      in gadget flags word */
#define  FLD_XCOLOUR        (14)  /* colour display icon linked to subfield
                                      within a flags word in the gadget's
                                      body */
#define  FLD_LENGTH         (15)  /* STRINGSET_INITIALMAX */
#define  FLD_END            (16)  /* this terminates an array of fielddefs */


typedef struct
{
    int valicon;
    int offset;
    Bool displayashex;
} IntegerFldRec, *IntegerFldPtr;


typedef struct
{
    int valicon;
    int lenicon;
    int upicon;
    int downicon;
    int valoffset;
    int lenoffset;
} MandAssStrFldRec, *MandAssStrFldPtr;


typedef struct
{
    int opticon;
    int valicon;
    int lenicon;
    int upicon;
    int downicon;
    int valoffset;
    int lenoffset;
} OptAssStrFldRec, *OptAssStrFldPtr;


typedef struct
{
    int icon;
    int offset;
} MandConstStrFldRec, *MandConstStrFldPtr;


typedef struct
{
    int opticon;
    int valicon;
    int offset;
} OptConstStrFldRec, *OptConstStrFldPtr;


typedef struct
{
    int opticon;
    unsigned mask;
    Bool flagmeanson;
} FlagFldRec, *FlagFldPtr;


typedef struct
{
    int opticon;
    int offset;
    unsigned mask;
    Bool flagmeanson;
} XFlagFldRec, *XFlagFldPtr;


typedef struct
{
    int valicon;
    int offset;
    unsigned mask;
    int shift;
} XPackedFldRec, *XPackedFldPtr;


typedef struct
{
    int opticon;
    unsigned mask;
    unsigned value;
} BitsFldRec, *BitsFldPtr;


typedef struct
{
    int dflticon;
    int othericon;
    int valicon;
    int offset;
} MandEventFldRec, *MandEventFldPtr;


typedef struct
{
    int dflticon;
    int othericon;
    int noneicon;
    int valicon;
    int offset;
    int mask;
} OptEventFldRec, *OptEventFldPtr;


typedef struct
{
    int opticon;
    int lcicon;
    int ucicon;
    int numicon;
    int otheropticon;
    int othervalicon;
    int lenicon;
    int upicon;
    int downicon;
    int valoffset;
    int lenoffset;
} AllowableFldRec, *AllowableFldPtr;


typedef struct
{
    int opticon;
    int valicon;
    int valoffset;
} LinkFldRec, *LinkFldPtr;


typedef struct
{
    int valicon;
    unsigned mask;
    int shift;
} ColourFldRec, *ColourFldPtr;


typedef struct
{
    int valicon;
    int offset;
    unsigned mask;
    int shift;
} XColourFldRec, *XColourFldPtr;


typedef struct
{
    int icon;
    int offset;
    int (*f) (GadgetPtr gadget);   /* returns minimum value (*) for field */
} LengthFldRec, *LengthFldPtr;


typedef union
{
    IntegerFldRec integer;
    MandAssStrFldRec mandassstr;
    OptAssStrFldRec optassstr;
    MandConstStrFldRec mandconststr;
    OptConstStrFldRec optconststr;
    FlagFldRec flag;
    XFlagFldRec xflag;
    XPackedFldRec xpacked;
    BitsFldRec bits;
    MandEventFldRec mandevent;
    OptEventFldRec optevent;
    AllowableFldRec allowable;
    LinkFldRec link;
    ColourFldRec colour;
    XColourFldRec xcolour;
    LengthFldRec length;
} FldDefRec, *FldDefPtr;


typedef struct
{
    int type;
    FldDefPtr def;
} FieldDefRec, *FieldDefPtr;


/*
 ** The following structures define actions which must be taken when the user
 *  clicks on certain icons in the dialogue box.
 *
 * For example, if the user clicks on the option icon for a Help message,
 *  then the Help text field must have its 'faded' status toggled.
 *
 * Possible actions are #defined in the following list.
 */

#define  ACT_FADE        (0)  /* this is a radio icon: fade a related icon */
#define  ACT_UNFADE      (1)  /* as above, but unfade a related icon */
#define  ACT_TOGGLEFADE  (2)  /* this is an option icon: toggle a related
                                  icon's 'faded' status */
#define  ACT_RADIO       (3)  /* this is a radio button: adjust-click must
                                  not switch it off */
#define  ACT_ADJUST      (4)  /* this is an adjuster arrow: a related
                                  writable must be updated */
#define  ACT_ALLOW       (5)  /* validation string option icon behaviour */
#define  ACT_COLOUR      (6)  /* desktop colour by pop-up menu */
#define  ACT_BUTTON      (7)  /* button type by pop-up menu */
#define  ACT_SPECIAL     (8)  /* escape route - calls a given function when
                                  the icon is SEL/ADJ-clicked */
#define  ACT_SPECIALX    (9)  /* as above, but is passed more parameters */
#define  ACT_END        (10)  /* this terminates an array of actions */


typedef struct
{
    int valicon;
} FadeClickRec, *FadeClickPtr;


typedef struct
{
    int valicon;
} UnFadeClickRec, *UnFadeClickPtr;


typedef struct
{
    int valicon;
} ToggleFadeClickRec, *ToggleFadeClickPtr;


typedef struct
{
    int valicon;    /* set to -1 if not relevant */
    int lenicon;
    Bool increase;
    int increment;
    int shiftincrement;
} AdjustClickRec, *AdjustClickPtr;


typedef struct
{
    int lcicon;
    int ucicon;
    int numicon;
    int otheropticon;
    int othervalicon;
} AllowClickRec, *AllowClickPtr;


typedef struct
{
    int displayicon;
    int menuicon;
    Bool allowtransparent;
} ColourClickRec, *ColourClickPtr;


typedef struct
{
    int displayicon;
    int menuicon;
} ButtonClickRec, *ButtonClickPtr;


typedef struct
{
    error * (*f) (GadgetPtr gadget);
} SpecialClickRec, *SpecialClickPtr;


typedef struct
{
    error * (*f) (GadgetPtr gadget, int icon, MouseClickPtr mouse);
} SpecialXClickRec, *SpecialXClickPtr;


typedef union
{
    FadeClickRec fade;
    UnFadeClickRec unfade;
    ToggleFadeClickRec togglefade;
    AdjustClickRec adjust;
    AllowClickRec allow;
    ColourClickRec colour;
    ButtonClickRec button;
    SpecialClickRec special;
    SpecialXClickRec specialx;
} ClickParamsRec, *ClickParamsPtr;


typedef struct
{
    int icon;
    int action;
    ClickParamsPtr params;
} ClickDefRec, *ClickDefPtr;


/*
 * The following structures define actions which must be taken when the user
 *  drops an object or gadget icon on certain icons in the dialogue box.
 *
 * For example, if the user drags a window template icon from a document
 *  window and drops it onto the "alternative window" icon in a DCS
 *  properties dialogue box, then the name of the window template must be
 *  inserted into the icon.
 *
 * Possible actions are #defined in the following list.
 */

#define  DROP_SET         (1)   /* single writable */
#define  DROP_SETOPT      (2)   /* opticon + writable */
#define  DROP_SETOPT2     (3)   /* opticon + writable + dependent icon */
#define  DROP_SETOPT3     (4)   /* opticon + writable + two dependents */


typedef struct
{
    int valicon;
} SetDropRec, *SetDropPtr;


typedef struct
{
    int valicon;
    int opticon;
} SetOptDropRec, *SetOptDropPtr;


typedef struct
{
    int valicon;
    int opticon;
    int othericon;
} SetOpt2DropRec, *SetOpt2DropPtr;


typedef struct
{
    int valicon;
    int opticon;
    int othericon1;
    int othericon2;
} SetOpt3DropRec, *SetOpt3DropPtr;


typedef union
{
    SetDropRec set;
    SetOptDropRec setopt;
    SetOpt2DropRec setopt2;
    SetOpt3DropRec setopt3;
} DropParamsRec, *DropParamsPtr;


 /* The kinds of drop that can occur are defined in the following list */

#define  GADGET_DROP  (1)
#define  OBJECT_DROP  (2)

typedef struct
{
    int type;     /* either a gadget or object drop */
    int class;    /* only for type OBJECT_DROP: -1 => any class accepted */
    int action;
    DropParamsPtr params;
} DropDetailsRec, *DropDetailsPtr;


typedef struct
{
    int icon;                 /* -2 => end-of-list,  -1 => any icon */
    DropDetailsPtr details;
} DropDefRec, *DropDefPtr;


/*
 * The following structure is a sub-structure for GadgetDefRec's.
 * It gives icon handles for those icons common to all gadget property
 *  dialogue boxes.
 */
typedef struct
{
    int firstwritable;       /* icon to take caret when dbox opened */
    int ok;                  /* OK action button */
    int cancel;              /* Cancel action button */
    int id;                  /* icon containing componentID field (or -1) */
    int window;              /* icon containing window name, or -1 if none */
    int hashelp;             /* option icon for help text */
    int help;                /* icon containing help text */
    int helpmax;             /* icon containing help text maximum length */
    int helpmaxadjup;        /* up adjuster for 'helpmax' icon */
    int helpmaxadjdown;      /* down adjuster for 'helpmax' icon */
    int faded;               /* option icon for 'faded' gadget */
} CommonIconsRec, *CommonIconsPtr;


/*
 * The following structure is a sub-structure of GadgetDefRec's.
 * It defines the location of the "alignment point" for the gadget, with
 *  possible values as shown in the #define list below.
 * If the 'horizontal' field is given as ALIGNPOS_SPECIAL, then the
 *  'vertical' field must contain the address of a function of the form
 *  error * f (GadgetPtr gadget, int *horizontal, int *vertical) which
 *  when called will assign appropriate values to 'horizontal' and
 *  'vertical'.
 * To allow static initializers to contain either integer values or function
 *  addresses, the type of 'vertical' has to be given as 'void *'; for
 *  consistency, I make 'horizontal' of the same type, and to ease set up
 *  I include the cast in the #defines.
 */
typedef struct
{
    void * horizontal;
    void * vertical;
} AlignmentPointRec, *AlignmentPointPtr;

#define  ALIGNPOS_CENTRE      (void *)0
#define  ALIGNPOS_TOP         (void *)1
#define  ALIGNPOS_LEFT        (void *)1
#define  ALIGNPOS_BOTTOM      (void *)2
#define  ALIGNPOS_RIGHT       (void *)2
#define  ALIGNPOS_SPECIAL     (void *)3 /* valid for 'horizontal' fld only */


/*
 * This structure defines the properties and structure of a gadget type.
 *
 * The 'fields' array is terminated by a field of type FLD_END, and the
 *  'clicks' array by an action of type ACT_END.
 */
typedef struct
{
    int type;                /* (just) the type */
    char *templatename;      /* name of dbox template in Templates file */
    WindowPtr proto;         /* prototype window for dbox */
    int protosize;           /* size of prototype window in bytes */
    BodyDefRec body;         /* defines structure of gadget body */
    FieldDefPtr fields;      /* defines the fields of the dbox */
    ClickDefPtr clicks;      /* defines the effect of mouse clicks in dbox */
    DropDefPtr drops;        /* defines the effect of dropping an object or
                                 gadget onto the dbox */
    CommonIconsRec icons;    /* gives handles of standard dbox icons */
    AlignmentPointRec align; /* describes position of "alignment point" */
    PointRec minsize;        /* minimum size permitted (multiple of 4) */
        /* if special processing is required ... */
    error * (*specialinit) (GadgetPtr gadget);  /* ... to initialise dbox */
    error * (*specialapply) (GadgetPtr gadget); /* ... to apply dbox */
} GadgetDefRec, *GadgetDefPtr;


/***************************************************************************/


/* ----------------------------------------------------------------------- */

/*
 * Each window object which is being edited (ie which has been sent to us
 * from the shell) is represented by a WindowObjRec. This includes data about
 * the editing window itself as well as data describing the window object.
 * 
 * Gadgets and keyboard shortcuts defined for the window are held in lists
 * attached to the WindowObjRec.
 *
 * Each gadget is represented by a GadgetRec, and each keyboard shortcut by
 * a KeyBoardShortcutRec.
 */


/* ---------------------------- Gadget records --------------------------- */

typedef struct
{
    /* data for/from template */

    unsigned int flags;
    short type;
    short size;
    RectRec bbox;
    ComponentID componentID;
    char *helpmessage;         /* malloc'd */
    int maxhelp;
} GadgetHeaderRec, *GadgetHeaderPtr;


/* this is the full definition of GadgetRec and *GadgetPtr */
struct _gadgetrec
{
    struct _gadgetrec *next;
    struct _windowobjrec *owner;

    GadgetDefPtr def; /* addresses the gadget type definition */

    Bool selected;
    WindowPtr dbox;   /* NULL if gadget properties dbox does not exist; note
                         that it only exists while open and on display */

    int localmaxhelp; /* contains a copy of the 'maxhelp' field in the gadget
                         header; this copy may take the value "-1" (*) */

    int *extension;   /* addresses any extension record */
    int extensionsize;       /* size of extension record in bytes */ 

    /* The following two fields must stay together; they form a "gadget
       description block" which is passed to the Toolbox SWI
       Window_PlotGadget during the redraw loop for the window */

    GadgetHeaderRec hdr;
    GadgetTemplateBodyRec body;

};   /* GadgetRec, *GadgetPtr */

  /* Note on the extension record:
   *
   * For normal gadgets, this contains copies of other "length" fields; these
   *  may take the the value "-1". It is considered a part of the GadgetRec
   *  itself, and is created when the gadget is created and destroyed when
   *  the gadget is freed.
   *
   * For "unknown" gadgets, this contains a copy of the gadget's body for use
   *  when the gadget's properties dialogue box is in existence. It is
   *  considered a part of the dialogue box, and is created when the dbox is
   *  created, and is destroyed when the dbox is deleted.
   */

/* ------------------------- Keyboard shortcuts -------------------------- */

typedef struct _keyboardshortcutrec
{
    unsigned int flags;
    int wimpkeycode;
    int keyevent;
    char *keyshow;             /* malloc */

    Bool selected;
    struct _keyboardshortcutrec *next;
} KeyBoardShortcutRec, *KeyBoardShortcutPtr;


/* ------------------------------- Windows ------------------------------- */

typedef struct
{
    int horizdiv;   /* OS units per division */
    int vertdiv;
    Bool show;
    Bool lock;
} GridRec, *GridPtr;


typedef struct
{
    unsigned int flags;
    char *helpmessage;         /* malloc */
    int maxhelp;
    char *pointershape;        /* malloc */
    int maxpointershape;
    int pointerxhot;
    int pointeryhot;
    char *menu;                /* malloc */

    ComponentID defaultfocus;

    int showevent;
    int hideevent;

    /* these fields must be maintained outside of the wimp window proper */

    unsigned int windowflags;
    int buttontype;               /* 0-15 - ie not shifted */
    unsigned char workBG;
    void *spritearea;
    char *title;
    int maxtitle;
} PropsRec, *PropsPtr;


typedef struct _windowobjrec
{
    PropsRec p;  /* fields which can be altered by the property dboxes */

    WindowPtr window;

    char *toolbaribl;
    char *toolbaritl;
    char *toolbarebl;
    char *toolbaretl;

    int numkeyboardshortcuts;
    KeyBoardShortcutPtr keyboardshortcuts;

    int numgadgets;
    GadgetPtr gadgets;

    /* other information */

    char name [MAX_OBJECT_NAME];  /* as passed to us from the shell */

    Opaque documentID;            /* together these provide a unique id */
    Opaque objectID;              /* for the object - quoted by the shell */ 

    Bool weakselection;           /* clear selection when menu is hidden */
    int numselected;
    int numpendingsnap;

    GridRec grid;

    Bool internal;                /* this is the palette */

    Bool modified;                /* shell's version is out-of-date */

    Bool pendingclose;            /* close when transfer to shell complete */

    WindowPtr mainpropsdbox;      /* NULL if corresponding dbox does not */
    WindowPtr otherpropsdbox;     /* exist; note that dbox only exists   */
    WindowPtr coloursdbox;        /* when it is open (on display)        */
    WindowPtr extentdbox;
    WindowPtr keycutsdbox;        /* The main dbox window  */
    WindowPtr keycutspane;        /* ... and its pane      */
    WindowPtr toolbarsdbox;
    int numkeys;
    KeyBoardShortcutPtr keys;     /* copy of shortcuts being edited */
    int numkeysselected;

    char *objectdata;             /* used when reassembling template */

} WindowObjRec, *WindowObjPtr;


/* These masks define the bits which are forced for the windowflags field */
#define  WF_FORCE0  (WF_OLD_GADGETS | WF_INFO_ONLY | WF_RESERVED)
#define  WF_FORCE1  (WF_NEWSTYLE)

/* These masks define the bits which are additionally forced when the window
    is displayed by !Window */
#define  WF_FORCE0_FOR_RESED  (WF_AUTO_REDRAW | WF_PANE | WF_ALLOW_OFF | WF_USER_SCROLL | WF_NO_REPEAT | WF_BACKDROP | WF_HOTKEYS | WF_KEEP_ON | WF_FREE_RIGHT | WF_FREE_BOTTOM)
#define  WF_FORCE1_FOR_RESED (WF_MOVEABLE)

/* These masks define the bits which are forced for the titleflags field */
#define  TF_FORCE1  (IF_TEXT | IF_VCENT | IF_INDIR)
#define  TF_FORCE0  ( ~(TF_FORCE1 | IF_HCENT | IF_RJUST) )

/* The button type for the window when displayed by !Window */
#define BUTTONTYPE_FOR_RESED  (10)    /* double/click/drag */


/* ----------------------------------------------------------------------- */


extern char *copystring (char *src);
extern error * clonestring (char **s);
extern Bool equalstrings (char *s, char *t);
extern error * windowedit_load_prototypes (void);
extern void windowedit_add_ears_to_bbox (RectPtr src, RectPtr dst);
extern error * windowedit_redraw_window (WindowRedrawPtr redraw,
                                         WindowObjPtr window);
extern error * windowedit_key_pressed (WindowObjPtr window,
    KeyPressPtr key, Bool *consumed);
extern error * windowedit_mouse_click (MouseClickPtr mouse,
    unsigned int modifiers, WindowObjPtr window);
extern error * windowedit_load (WindowObjPtr window,
    ResourceFileObjectTemplateHeaderPtr object,
    MessageResEdObjectLoadPtr load);
extern error * windowedit_rename_window (WindowObjPtr window, char *name);
extern void windowedit_get_selection_bbox (WindowObjPtr window,
    RectPtr bbox);
extern error * windowedit_focus_claim (WindowObjPtr window);
extern error * windowedit_raise_window (WindowObjPtr window);
extern error * windowedit_redisplay_window (WindowObjPtr window);
extern error * windowedit_reopen_window (WindowPtr win, WindowObjPtr window);
extern error * windowedit_close_window (WindowObjPtr window, Bool notifyshell);
extern error * windowedit_close_wind (WindowObjPtr window);
extern int windowedit_object_size (WindowObjPtr window, int *bodysize,
    int *stringsize, int *msgsize, int *numrelocs);
extern error * windowedit_save_object_to_memory (WindowObjPtr window, char *buffer,
    int bodysize, int stringsize, int msgsize, int numrelocs);
extern Bool windowedit_help_text (
    WindowObjPtr window,
    PointPtr mouse,
    char *reply
);

#endif
